/**
 * 数据脱敏工具
 *
 * @fileoverview 用于在日志记录前对敏感信息进行脱敏处理
 */

/**
 * 敏感字段列表（这些字段会被完全移除）
 */
const SENSITIVE_FIELDS = [
  'password',
  'pwd',
  'passwd',
  'token',
  'accessToken',
  'refreshToken',
  'apiKey',
  'apikey',
  'secret',
  'secretKey',
  'privateKey',
  'creditCard',
  'cardNumber',
  'cvv',
  'ssn',
  'socialSecurityNumber',
]

/**
 * 需要脱敏的字段列表（这些字段只显示部分信息）
 */
const PARTIAL_MASK_FIELDS = [
  'passport',
  'passport_number',
  'passportNumber',
  'phone',
  'phone_number',
  'phoneNumber',
  'email', // 可以保留邮箱，但也可以考虑脱敏
]

/**
 * 脱敏护照号码（只显示后4位）
 *
 * @param passport - 护照号码
 * @returns 脱敏后的护照号码
 */
export function sanitizePassport(passport: string | undefined | null): string {
  if (!passport || typeof passport !== 'string') {
    return '[REDACTED]'
  }

  if (passport.length <= 4) {
    return '****'
  }

  return `****${passport.slice(-4)}`
}

/**
 * 脱敏电话号码（只显示后4位）
 *
 * @param phone - 电话号码
 * @returns 脱敏后的电话号码
 */
export function sanitizePhone(phone: string | undefined | null): string {
  if (!phone || typeof phone !== 'string') {
    return '[REDACTED]'
  }

  const digits = phone.replace(/\D/g, '')
  if (digits.length <= 4) {
    return '****'
  }

  return `****${digits.slice(-4)}`
}

/**
 * 脱敏邮箱（只显示用户名部分和域名，隐藏中间部分）
 *
 * @param email - 邮箱地址
 * @returns 脱敏后的邮箱地址
 */
export function sanitizeEmail(email: string | undefined | null): string {
  if (!email || typeof email !== 'string' || !email.includes('@')) {
    return '[REDACTED]'
  }

  const [username, domain] = email.split('@')
  if (username.length <= 2) {
    return `**@${domain}`
  }

  return `${username.slice(0, 2)}**@${domain}`
}

/**
 * 对数据进行脱敏处理
 *
 * @param data - 要脱敏的数据
 * @returns 脱敏后的数据
 */
export function sanitize(data: any): any {
  if (data === null || data === undefined) {
    return data
  }

  // 处理字符串（如果包含敏感信息模式）
  if (typeof data === 'string') {
    // 检查是否包含护照号格式（E+数字）
    if (/^E\d+$/.test(data)) {
      return sanitizePassport(data)
    }
    // 检查是否包含电话号码格式
    if (/^\+?\d[\d\s\-()]+$/.test(data.replace(/\s/g, ''))) {
      return sanitizePhone(data)
    }
    return data
  }

  // 处理数组
  if (Array.isArray(data)) {
    return data.map(item => sanitize(item))
  }

  // 处理对象
  if (typeof data === 'object') {
    const sanitized: any = {}

    for (const [key, value] of Object.entries(data)) {
      const lowerKey = key.toLowerCase()

      // 敏感字段：完全移除
      if (SENSITIVE_FIELDS.some(field => lowerKey.includes(field.toLowerCase()))) {
        sanitized[key] = '[REDACTED]'
        continue
      }

      // 部分脱敏字段
      if (lowerKey.includes('passport')) {
        sanitized[key] = sanitizePassport(value as string)
        continue
      }

      if (lowerKey.includes('phone')) {
        sanitized[key] = sanitizePhone(value as string)
        continue
      }

      if (lowerKey.includes('email') && typeof value === 'string') {
        sanitized[key] = sanitizeEmail(value)
        continue
      }

      // 递归处理嵌套对象
      sanitized[key] = sanitize(value)
    }

    return sanitized
  }

  return data
}
